#include "palmvein.h"
#include "palmvein_com.h"
#include "palmvein_protocol.h"
#include "palmvein_encrypt.h"

/* debug print interpalmvein */
#if defined(PALMVEIN_DEBUG)
#define PALMVEIN_TASK_DEBUG_LOG(format, ...) OSAL_LOG(C_CYAN format C_NONE, ##__VA_ARGS__)
#define __PALMVEIN_TASK_DEBUG_LOG(format, ...) __OSAL_LOG(C_CYAN format C_NONE, ##__VA_ARGS__)
#else
#define PALMVEIN_TASK_DEBUG_LOG(format, ...)
#define __PALMVEIN_TASK_DEBUG_LOG(format, ...) //__OSAL_LOG(C_CYAN format C_NONE, ##__VA_ARGS__)
#endif

#define PALMVEIN_TASK_LOG(format, ...) OSAL_LOG(C_LIGHT_CYAN format C_NONE, ##__VA_ARGS__)
#define __PALMVEIN_TASK_LOG(format, ...) __OSAL_LOG(C_LIGHT_CYAN format C_NONE, ##__VA_ARGS__)




#define MASTER_TO_PALMVEIN_MSG_NUM      10						  //主控给掌静脉的循环消息队列深度



static uint16_t id_to_delete = 0;		//被删除的id
static uint8_t power_off_flag = 0;		//断电标志
static uint32_t self_learn_timeout = 0;		//自学习时间戳


/*删除的掌静脉编号*/
static struct
{
	uint16_t userId; //需要删除的掌静脉ID（存储于掌静脉模组）
	uint8_t userNum; //掌静脉用户编号（存储于锁）
} palmveinDeleteUser;





Palmvein_Param_stu_t palmveinMsgParam;          /*掌静脉控制参数结构体*/

/*****************************************************************************************************************************/

static FlagStatus palmveinTaskNoPalmveinFlag = RESET; //未检测到掌静脉标志  SET：未检测到掌静脉   RESET：检测到掌静脉

static RingBufferHandle_t palmveinCtrl_rbHandle = NULL;         /* 应用层操作循环队列句柄 */


static void Palmvein_Mode_Update(PalmVein_ctrl_enum_t msgId);
static void Palmvein_Mode_SeletDeal(Palmvein_DealParam_stu_t *param);
static void Palmvein_Event_Update(void);
static ErrorStatus CtrlId_ReadRingBuff(void);

static uint8_t mPox_buffer[1280] = {0};



/**
  * @brief  读取量产标志位
  */
static uint8_t Palmvein_ReadPalmveinReleaseFlag(void)
{
	uint8_t palmveinReleaseFlag;
	OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmveinReleaseFlag), &palmveinReleaseFlag, 1);
	return palmveinReleaseFlag;
}

/**
  * @brief  写量产标志位
  * @note	This flag will be reset every time the program is re-burned 
  *
  * @param  0:not set    1:set
  */
static ErrorStatus Palmvein_SetPalmveinReleaseFlag(uint8_t flag)
{
	return OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmveinReleaseFlag), &flag, 1);
}


/**
  * @brief  掌静脉检测标志设置初始值
  *
  * @note  每次启动验证时置位标志为已经检测到掌静脉
  */
static void Palmvein_CheckFlag_Init(void)
{
	palmveinTaskNoPalmveinFlag = RESET;
}

/**
  * @brief  未检测到掌静脉标志置位
  *
  * @note
  */
static void Palmvein_Check(void *pdata)
{
	Palmvein_NotePalmveinStatus_stu_t *pdatabuf = (Palmvein_NotePalmveinStatus_stu_t *)pdata;
	/*未检测到掌静脉标志  SET：未检测到掌静脉   RESET：检测到掌静脉*/
	palmveinTaskNoPalmveinFlag = (pdatabuf->status == PALMVEIN_STATE_NOPALMVEIN) ? SET : RESET;
}

/**
  * @brief  判断是否检测到掌静脉
  *
  * @return SET：未检测到掌静脉   
  * 		RESET：检测到掌静脉
  */
static FlagStatus Palmvein_Check_Result(void)
{
	/*未检测到掌静脉标志  SET：未检测到掌静脉   RESET：检测到掌静脉*/
	FlagStatus ret = (palmveinTaskNoPalmveinFlag == SET) ? SET : RESET;
	return ret;
}

/**
  * @brief  写入掌静脉内部id
  */
ErrorStatus Palmvein_WriteUserId(uint8_t num, uint16_t *userId)
{
	return OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id) + num * 2, userId, 2);
}

/**
  * @brief  读取掌静脉内部id
  */
ErrorStatus Palmvein_ReadUserId(uint8_t num, uint16_t *userId)
{
	return OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id) + num * 2, userId, 2);
}

/**
  * @brief  删除单个掌静脉索引
  * @param  num : 索引号
  */
ErrorStatus Palmvein_DeleteIndex(uint8_t num)
{
	uint16_t userId = 0xffff;
	return OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id) + num * 2, (void *)&userId, 2);
}

/**
  * @brief  删除所有掌静脉索引数据
  */
ErrorStatus Palmvein_DeleteAllIndex(void)
{
	uint16_t userId[MAX_PALMVEIN_NUM];
	memset(userId, 0xff, sizeof(userId));
	return OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id), (void *)&userId, sizeof(userId));
}

/**
  * @brief  删除所有掌静脉普通用户索引数据
  */
ErrorStatus Palmvein_DeleteAllNormalIndex(void)
{
	uint16_t userId[MAX_PALMVEIN_NUM-1];
	memset(userId, 0xff, sizeof(userId));
	return OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id)+2, (void *)&userId, sizeof(userId));
}

/**
  * @brief  根据掌静脉id搜索索引号
  * @param  userId : 掌静脉ID
  */
int32_t Palmvein_Search_Index(uint8_t *userId)
{
	uint8_t read[2];
	int num = 0;
	for(num = 0; num < MAX_PALMVEIN_NUM; num++)
	{
		OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id) + num * 2, &read, sizeof(read));
		printf("%d : 0x%04x\r\n", num, *(uint16_t *)read);
		if(*(uint16_t *)read == *(uint16_t *)userId)
		{
			return num;
		}
	}
	return -1;
}

uint8_t read_buff[MAX_PALMVEIN_NUM*2];

/**
  * @brief  读取所有掌静脉id
  * 
  */
void Palmvein_Read_All_UserId(void)
{
	OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id), &read_buff, sizeof(read_buff));
}


/**
  * @brief  掌静脉查询比较
  * @param  module_userId : 掌静脉ID
  */
int32_t Palmvein_Search_Compare(uint8_t *module_userId)
{
	uint8_t read[2];
	int num = 0;

	for(num = 0; num < MAX_PALMVEIN_NUM; num++)
	{
		//每次读取一个id进行比较
		memcpy(read,read_buff+num*2,2);
		//OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmvein_user_id) + num * 2, &read, sizeof(read));
		//PALMVEIN_TASK_LOG("%d : %x", num, *(uint16_t *)read);
		if(*(uint16_t *)read == *(uint16_t *)module_userId)
		{
			printf("[%02d]    : 0x%04x \r\n",num,*(uint16_t *)module_userId);
			return 1;
		}
	}
	return 0;
}

/**
  * @brief  返回锁当前的时间戳
  *
  * @return 返回UTC时间（以 1970.1.1 00:00:00 为起始时间的秒计数）
  */
static uint32_t Palmvein_GetUtcTimestamp(void)
{
	uint32_t timestamp;
	OSAL_TimeGet(&timestamp, T_UTC);
	return timestamp;
}

/**
  * @brief  写掌静脉模块版本号
  */
ErrorStatus Palmvein_WritePalmveinVersion(uint8_t *pData, uint8_t len)
{
	ErrorStatus status = SUCCESS;
	uint8_t temp[PALMVEIN_VERSION_LEN] = {0};
	OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmveinVesion), temp, PALMVEIN_VERSION_LEN);
	if (strcmp((char *)pData, (char *)&temp) != 0)
	{
		PALMVEIN_TASK_LOG("update palmvein version: %s\r\n", pData);
		status = OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmveinVesion), pData, PALMVEIN_VERSION_LEN);
	}

	return status;
}

/**
  * @brief  读掌静脉版本号
  */
static ErrorStatus Palmvein_Read_Version(uint8_t *pData, uint8_t *pLen)
{
	OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmveinVesion), pData, PALMVEIN_VERSION_LEN);
	uint8_t version_len = strlen(pData);
	for (int i = 1; i < version_len; i++)
	{
		if (!((pData[i] >= '0' && pData[i] <= '9') || pData[i] == '.'))
		{
			return ERROR;
		}
	}
	*pLen = version_len;
	PALMVEIN_TASK_LOG("read palmvein version: %s\r\n", pData);
	return SUCCESS;
}

/**
  * @brief  read palmvein model读掌静脉型号
  */
static ErrorStatus Palmvein_Read_Model(uint8_t *pData)
{
	ErrorStatus ret = OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmveinModel), pData, PALMVEIN_MODEL_LEN);
	PALMVEIN_TASK_LOG("read palmvein model: %s\r\n", pData);
	return ret;
}

/**
  * @brief  write palmvein model
  */
ErrorStatus Palmvein_Write_Model(uint8_t *pData)
{
	ErrorStatus status = SUCCESS;
	uint8_t temp[PALMVEIN_MODEL_LEN] = {0};
	OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmveinModel), temp, PALMVEIN_MODEL_LEN);
	if (strcmp((char *)pData, (char *)&temp) != 0)
	{
		PALMVEIN_TASK_LOG("update palmvein model: %s\r\n", pData);
		status = OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmveinModel), pData, PALMVEIN_MODEL_LEN);
	}
	return status;
}

/**
  * @brief 读掌静脉SN
  */
static ErrorStatus Palmvein_ReadPalmveinSN(uint8_t *pSN)
{
	int i = 0;
	ErrorStatus ret = ERROR;
	OSAL_NvRead(OSAL_OFFSET(NvPalmvein_stu_t, palmveinSn), pSN, PALMVEIN_SN_LEN);
	for (i = 0; i < PALMVEIN_SN_LEN; i++)
	{
		if (!((pSN[i] >= '0' && pSN[i] <= '9') || (pSN[i] >= 'a' && pSN[i] <= 'z') || (pSN[i] >= 'A' && pSN[i] <= 'Z') || (pSN[i] == '-')))
		{
			break;
		}
	}
	if (i >= PALMVEIN_SN_LEN - 5) //支持15~20的变长  掌静脉模组技术支持答复掌静脉sn长度为17~20个字节
	{
		ret = SUCCESS;
	}
	return ret;
}

/**
  * @brief  写掌静脉SN
  */
static ErrorStatus Palmvein_WritePalmveinSN(uint8_t *pSN, uint8_t len)
{
	return OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmveinSn), pSN, PALMVEIN_SN_LEN);
}

/**
  * @brief  掌静脉模组初始化加密密钥处理函数
  *
  * @note
  */
static void Palmvein_InitEncryption_Process(void)
{
	uint8_t seeddata[4] = {0};
	uint32_t timedata = 0;
	PalmveinEncrypt_GenerateRandomNumber(seeddata); //获取随机数
	// timedata = Palmvein_GetUtcTimestamp();			//获取时间
	timedata = 1675163839;
	Palmvein_P_Send_InitEncryption_CMD(seeddata, 4, (uint8_t *)&timedata, 4);
	PalmveinEncrypt_GenencKey(seeddata); //生成aes密钥
}

/************************************************************************************************/
/*****************************  掌静脉推送消息选择函数    STATR   ***********************************/
/************************************************************************************************/

/**
  * @brief  推送掌静脉消息
  * @note   掌静脉模块产生的动作，通知主任务
  *         
  * @param  PalmVeinActionType_enum_t:事件类型
  * @param  id:用户ID
  */
static void Palmvein_PublishMsg(PalmVeinActionType_enum_t action, uint8_t id)
{
	PalmVeinMsg_t palmveinMsg;
	palmveinMsg.action = action;
	palmveinMsg.id = id;
	OSAL_MessagePublish(&palmveinMsg, sizeof(palmveinMsg));
}


/**
  * @brief  掌静脉录入结果推送
  *
  * @note
  */
static void Palmvein_Enroll_SendActionMsg(Palmvein_Result_enum_t result, uint8_t num)
{
	PalmVeinActionType_enum_t action = PALMVEIN_ACTION_MAX;
	uint8_t numbuf = num;

	switch (result)
	{
		case RESULT_SUCCESS_REPORT:
			action = PALMVEIN_ACTION_ADD_OK;
			break;
		case RESULT_FAIL_REPORT:
			action = PALMVEIN_ACTION_ADD_ERR;
			break;
		case RESULT_PALMVEIN_ENROLLED:
			action = PALMVEIN_ACTION_ADD_REPEAT;
			break; //掌静脉已存在
		default:
			break;
	}

	if (PALMVEIN_ACTION_MAX != action)
	{
		Palmvein_PublishMsg(action, numbuf);
	}
}

/**
  * @brief  掌静脉验证结果推送
  *
  * @note
  */
static void Palmvein_Verify_SendActionMsg(Palmvein_Result_enum_t result, uint8_t num)
{
	PalmVeinActionType_enum_t action = PALMVEIN_ACTION_MAX;
	uint8_t numbuf = num;

	switch (result)
	{
		case RESULT_SUCCESS_REPORT:
			action = PALMVEIN_ACTION_VERIFY_OK;
			break;
		case RESULT_FAIL_REPORT:
			action = PALMVEIN_ACTION_VERIFY_ERR;
			break;

		case RESULT_END:
			action = PALMVEIN_ACTION_VERIFY_END;
			break;

		case RESULT_NO_PALMVEIN:			   //未检测到掌静脉
			action = PALMVEIN_ACTION_TIME_OUT; //无掌静脉，以超时结果上报
			break;

		case RUSULT_MODULE_BREAKDOWN:
			action = PALMVEIN_ACTION_MODULE_BREAKDOWN;
		default:
			break;
	}

	if (PALMVEIN_ACTION_MAX != action)
	{
		Palmvein_PublishMsg(action, numbuf);
	}
}

/**
  * @brief  掌静脉删除结果发送给主任务
  *
  * @note
  */
static void Palmvein_Delete_SendActionMsg(Palmvein_Result_enum_t result, uint8_t num)
{
	PalmVeinActionType_enum_t action = PALMVEIN_ACTION_MAX;
	uint8_t numbuf = num;
	PALMVEIN_TASK_LOG("delete send msg ,result:%d",result);

	switch (result)
	{
		case RESULT_SUCCESS_REPORT:
			action = PALMVEIN_ACTION_DEL_OK;
			break;

		case RESULT_FAIL_REPORT:
			action = PALMVEIN_ACTION_DEL_FAIL;
			break; //掌静脉已存在

		case RESULT_NO_PALMVEIN:
			action = PALMVEIN_ACTION_TIME_OUT;
			break; //无掌静脉，以超时结果上报
		default:

			break;
	}

	if (PALMVEIN_ACTION_MAX != action)
	{
		Palmvein_PublishMsg(action, numbuf);
	}
}



/**
  * @brief  根据掌静脉模组返回“掌静脉方向错误”判断掌静脉偏转方向
  *
  * @note
  */
static PalmVeinActionType_enum_t Palmvein_Single_Enroll_ERR_Dir_Reminder(int16_t yaw, int16_t pitch, int16_t roll)
{
	PalmVeinActionType_enum_t ret = PALMVEIN_ACTION_MAX;
	PALMVEIN_TASK_LOG("siggle enroll yaw=%#2x,pitch=%#2x, roll=%#2x", yaw, pitch, roll);
	if (yaw > PALMVEIN_MIDDLE_MAX)
	{
		ret = PALMVEIN_ACTION_LEFT_REMINDER;
	}
	else if (yaw < PALMVEIN_MIDDLE_MIN)
	{
		ret = PALMVEIN_ACTION_RIGHT_REMINDER;
	}

	else if (pitch > PALMVEIN_MIDDLE_MAX)
	{
		ret = PALMVEIN_ACTION_UP_REMINDER;
	}
	else if (pitch < PALMVEIN_MIDDLE_MIN)
	{
		ret = PALMVEIN_ACTION_DOWN_REMINDER;
	}

	else if (roll > PALMVEIN_ROLL_MAX //歪头
			 || roll < PALMVEIN_ROLL_MIN)
	{
		ret = PALMVEIN_ACTION_MIDDLE_REMINDER;
	}
	return ret;
}

/**
  * @brief  录入和验证过程掌静脉状态提醒
  *
  * @note
  */
static void Palmvein_PalmveinStatus_Reminder(void *pdata)
{
	uint8_t num = INVALID_NUM;
	PalmVeinActionType_enum_t action = PALMVEIN_ACTION_MAX;
	s_note_data_palmvein *pdatabuf = (s_note_data_palmvein *)pdata;
	//PALMVEIN_TASK_DEBUG_LOG("PalmveinStatus:state:%#4x,left:%#4x,  top:%#4x,	right:%#4x, bottom:%#4x, yaw:%#4x, pitch:%#4x, roll:%#4x,",\
									pdata->state,pdata->left,pdata->top,	pdata->right,pdata->bottom,pdata->yaw,pdata->pitch,pdata->roll);
	PALMVEIN_TASK_LOG(C_LIGHT_PURPLE C_COLOR "Reminder PalmveinStatus:state:%d" C_NONE, pdatabuf->status);

	switch (pdatabuf->status)
	{
		case PALMVEIN_STATE_NOTMID: //手掌未居中
			action = PALMVEIN_ACTION_NOT_MIDDLE;
			break;
		case PALMVEIN_STATE_TOOUP: //手掌放置太高
			action = PALMVEIN_ACTION_FAR;
			break;
		case PALMVEIN_STATE_TOODOWN: //手掌放置太低
			action = PALMVEIN_ACTION_CLOSE;
			break;
		case PALMVEIN_STATE_NOPALMVEIN:		//未检测到
			action = PALMVEIN_ACTION_NOPALMVEIN;
			break;

		default:
			break;
	}

	if (PALMVEIN_ACTION_MAX != action)
	{
		Palmvein_PublishMsg(action, num);
	}

}


/**
  * @brief  掌静脉事件更新处理
  *
  * @note
  */
static void Palmvein_Event_Update(void)
{
	Palmvein_DealParam_stu_t parambuf;
	parambuf.data = NULL;
	PALMVEIN_TASK_LOG("cur ctrlId:%d\r\n",palmveinModuleStatus.ctrlId);

	switch (palmveinModuleStatus.ctrlId)
	{
			//录入掌静脉
		case PALMVEIN_CTRL_ENROLL:
			parambuf.event = PALMVEIN_EVENT_START_ENROLL;
			break;

			//验证掌静脉
		case PALMVEIN_CTRL_VERIFY:
			parambuf.event = PALMVEIN_EVENT_START_VERIFY;
			break;

			//验证删除
		case PALMVEIN_CTRL_VERIFY_DELETE:
			parambuf.event = PALMVEIN_EVENT_START_VERIFY_DELETE;
			break;

			//删除掌静脉
		case PALMVEIN_CTRL_DELETE:
			parambuf.event = PALMVEIN_EVENT_START_DELETE;
			break;

			//恢复出厂设置
		case PALMVEIN_CTRL_FACTORY_RESET:
			parambuf.event = PALMVEIN_EVENT_FACTORY;
			break;

			//获取版本号
		case PALMVEIN_CTRL_GET_VERSION:
			parambuf.event = PALMVEIN_EVENT_GET_VERSION;
			break;

			//设置演示模式
		case PALMVEIN_CTRL_SET_DEMO_MODE:
			parambuf.event = PALMVEIN_EVENT_SET_DEMO_MODE;
			break;

			//设置工作模式
		case PALMVEIN_CTRL_SET_WORK_MODE:
			parambuf.event = PALMVEIN_EVENT_SET_WORK_MODE;
			break;

			//设置量产秘钥
		case PALMVEIN_CTRL_SET_RELEASE_ENC:
			parambuf.event = PALMVEIN_EVENT_SET_RELEASE_ENC_KEY;
			break;

		case PALMVEIN_CTRL_OTA_POWER:
			parambuf.event = PALMVEIN_EVENT_START_OTA;
			break;

			//启动OTA
		case PALMVEIN_CTRL_START_OTA:
			parambuf.event = PALMVEIN_EVENT_START_OTA;
			break;
		
		default:
			break;
	}

	//根据当前模式选择处理
	Palmvein_Mode_SeletDeal(&parambuf);
}

/************************************************************************************************/
/******************************  掌静脉推送消息选择函数    END   ***********************************/
/************************************************************************************************/

/************************************************************************************************/
/********************************  掌静脉功能处理函数    STATR   ***********************************/
/************************************************************************************************/

//TODO测试无加密处理
static void Palmvein_Not_Encryp_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;
	static uint8_t first_flag = 0;

	switch (parambuf->event)
	{
			//上电完成或上单超时
		case PALMVEIN_EVENT_POWER_ON_READY:
		case PALMVEIN_EVENT_POWER_ON_TIMEOUT:
			
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_EXECUTE;

            CtrlId_ReadRingBuff();          //读队列 
			break;
		
		default:
			break;
	}
}


/**
  * @brief  掌静脉模组加密处理
  * @note
  */
static void Palmvein_Encryp_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;
	static uint8_t first_flag = 0;

	switch (parambuf->event)
	{
			//上电完成或上单超时
		case PALMVEIN_EVENT_POWER_ON_READY:
		case PALMVEIN_EVENT_POWER_ON_TIMEOUT:
			//如果已产测，第一次上电和设置产测时，还是使用临时秘钥
			if ((first_flag) && (1 == Palmvein_ReadPalmveinReleaseFlag()) && (palmveinModuleStatus.ctrlId != PALMVEIN_CTRL_SET_RELEASE_ENC)) //已成功发送加密逻辑序列 release 模式
			{
				//已产测，开始初始化秘钥
				__PALMVEIN_TASK_LOG("Start init encryption\r\n");
				Palmvein_InitEncryption_Process();
			}
			else
			{
				first_flag = 1;
				//未产测，发生临时秘钥
				__PALMVEIN_TASK_LOG("Start debug encryption key\r\n");
				Palmvein_P_Send_DebugEncrytionKeyNum_Cmd((uint8_t *)&palmveinKeyIndex, PALMVEIN_KEY_SIZE);
			}
			break;

			//临时秘钥完成
		case PALMVEIN_EVENT_DEBUG_ENC_READY:
			__PALMVEIN_TASK_LOG("Start init encryption\r\n");
			Palmvein_InitEncryption_Process();
			break;

			//随机数初始化完成
		case PALMVEIN_EVENT_INIT_ENCRYPTION_READY:
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_EXECUTE;

            CtrlId_ReadRingBuff();          //读队列 
			break;

		default:
			break;
	}

}

/**
  * @brief  掌静脉模组录入处理
  * @note
  */
static void Palmvein_Enroll_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;
	s_msg_reply_enroll_data *replybuf = (s_msg_reply_enroll_data *)parambuf->data;
	static uint32_t startTime;
	uint32_t currentTime = OSAL_GetTickCount();
	uint16_t user_id;

	switch (parambuf->event)
	{
			//启动录入
		case PALMVEIN_EVENT_START_ENROLL:
			Palmvein_P_Send_StartEnroll_CMD(palmveinMsgParam.num,palmveinMsgParam.type);
			startTime = OSAL_GetTickCount();
			break;

			//掌静脉信息返回
		case PALMVEIN_EVENT_NID_PALMVEIN_STATUS:
			if (OSAL_PastTime(currentTime, startTime) > PALMVEIN_REMINDER_INTERVAL) //间隔时间提醒
			{
				startTime = OSAL_GetTickCount();
				s_note_data_palmvein *notebuf = (s_note_data_palmvein *)parambuf->data;
				//推送掌静脉信息给应用层
				Palmvein_PalmveinStatus_Reminder(notebuf);
			}
			break;

			//录入完成
		case PALMVEIN_EVENT_ENROLL_SUCCESS:
			user_id = (replybuf->user_id_heb << 8 ) | replybuf->user_id_leb;
			PALMVEIN_TASK_LOG("enroll result = %d, num: %d, user_id: %d\r\n", parambuf->result, palmveinMsgParam.num,user_id);
			/* 存储userid */
			Palmvein_WriteUserId(palmveinMsgParam.num, &user_id);
			Palmvein_Enroll_SendActionMsg(parambuf->result,palmveinMsgParam.num);
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
			Palmvein_Event_Deal(&parambuf);
			break;

			//录入失败
		case PALMVEIN_EVENT_ENROLL_FAIL:
			Palmvein_Enroll_SendActionMsg(parambuf->result,palmveinMsgParam.num);
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
			Palmvein_Event_Deal(&parambuf);
			break;

			//超时
		case PALMVEIN_EVENT_TIMEOUT:
			Palmvein_Enroll_SendActionMsg(parambuf->result,palmveinMsgParam.num);
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_SLEEPED;
			Palmvein_Event_Deal(&parambuf);
			break;

		default:
			break;

	}
}


/**
  * @brief  掌静脉模组验证处理
  * @note
  */
static void Palmvein_Verify_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;
	s_msg_reply_verify_data *replybuf = (s_msg_reply_verify_data *)parambuf->data;
	static uint32_t startTime;
	uint32_t currentTime = OSAL_GetTickCount();

	switch (parambuf->event)
	{
			//启动验证
		case PALMVEIN_EVENT_START_VERIFY:
			Palmvein_P_Send_StartVerity_CMD(1);
			Palmvein_CheckFlag_Init();
			startTime = OSAL_GetTickCount();
			break;

			//验证删除
		case PALMVEIN_EVENT_START_VERIFY_DELETE:
			Palmvein_P_Send_StartVerity_CMD(4);
			Palmvein_CheckFlag_Init();
			startTime = OSAL_GetTickCount();
			break;

			//掌静脉信息返回
		case PALMVEIN_EVENT_NID_PALMVEIN_STATUS:
			// Palmvein_Check(parambuf->data);
			// if (OSAL_PastTime(currentTime, startTime) > PALMVEIN_REMINDER_INTERVAL) //间隔时间提醒
			// {
			// 	startTime = OSAL_GetTickCount();
			// 	s_note_data_palmvein *replybuf = (s_note_data_palmvein *)parambuf->data;
			// 	//推送掌静脉信息给应用层
			// 	Palmvein_PalmveinStatus_Reminder(replybuf);
			// }
			break;

			//验证成功
		case PALMVEIN_EVENT_VERIFY_SUCCESS:
			id_to_delete = (replybuf->user_id_heb << 8 ) | replybuf->user_id_leb;
			Palmvein_Verify_SendActionMsg(parambuf->result,replybuf->user_name[0]);
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
			Palmvein_Event_Deal(&parambuf);
			Palmvein_Verify_SendActionMsg(RESULT_END,replybuf->user_name[0]);
			break;

			//验证失败,超时
		case PALMVEIN_EVENT_VERIFY_FAIL:
		case PALMVEIN_EVENT_TIMEOUT:
			parambuf->result = ((parambuf->result != RESULT_VERIFY_FAIL_REPORT) && SET == Palmvein_Check_Result()) ? RESULT_NO_PALMVEIN : RESULT_FAIL_REPORT;	
			PALMVEIN_TASK_LOG("Verify result: %d \r\n", parambuf->result);
			Palmvein_Verify_SendActionMsg(parambuf->result,INVALID_NUM);
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
			Palmvein_Event_Deal(&parambuf);
			break;

		default:
			break;

	}
}


/**
  * @brief  掌静脉模组删除处理
  * @note
  */
static void Palmvein_Delete_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;
	s_msg_reply_verify_data *replybuf = (s_msg_reply_verify_data *)parambuf->data;
	static uint32_t startTime;
	uint32_t currentTime = OSAL_GetTickCount();

	switch (parambuf->event)
	{
			//启动删除
		case PALMVEIN_EVENT_START_DELETE:
			if (PALMVEIN_DELETE_ALL_NUN == palmveinMsgParam.num)
			{
				//删除全部掌静脉
				palmveinDeleteUser.userId = PALMVEIN_DELETE_ALL_NUN | (PALMVEIN_DELETE_ALL_NUN < 8);
				palmveinDeleteUser.userNum = PALMVEIN_DELETE_ALL_NUN;
				Palmvein_P_Send_Start_DelAll_CMD(); //发送删除全部掌静脉的消息给掌静脉模组
			}
			else
			{
				//按编号删除
				palmveinDeleteUser.userId = id_to_delete;
				palmveinDeleteUser.userNum = palmveinMsgParam.num;
				PALMVEIN_TASK_LOG("Delete userNum: %02d, userId: 0x%04x",palmveinDeleteUser.userNum,palmveinDeleteUser.userId);
				Palmvein_P_Send_Start_DelUser_CMD(palmveinDeleteUser.userId);
			}
			Palmvein_CheckFlag_Init();
			startTime = OSAL_GetTickCount();
			break;

			//恢复出厂设置
		case PALMVEIN_EVENT_FACTORY:
			Palmvein_P_Send_Factory_CMD();
			break;

			//删除完成
		case PALMVEIN_EVENT_DELETE_FINISH:
			PALMVEIN_TASK_LOG("PALMVEIN_EVENT_DELETE_FINISH");
			Palmvein_Delete_SendActionMsg(parambuf->result,palmveinDeleteUser.userNum);
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
			Palmvein_Event_Deal(&parambuf);
			break;

			//验证失败,超时
		case PALMVEIN_EVENT_VERIFY_FAIL:
		case PALMVEIN_EVENT_TIMEOUT:
			PALMVEIN_TASK_LOG("PALMVEIN_EVENT_VERIFY_FAIL  PALMVEIN_EVENT_TIMEOUT");
			parambuf->result = ((parambuf->result != RESULT_VERIFY_FAIL_REPORT) && SET == Palmvein_Check_Result()) ? RESULT_NO_PALMVEIN : RESULT_FAIL_REPORT;	
			Palmvein_Delete_SendActionMsg(parambuf->result,palmveinDeleteUser.userNum);
			palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
			Palmvein_Event_Deal(&parambuf);
			break;


		default:
			break;

	}


}

/**
  * @brief  掌静脉模组终止处理
  * @note
  */
static void Palmvein_Idle_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_P_Send_Reset_CMD(); //发送终止当前操作指令（验证、注册）
	palmveinModuleStatus.curStatus = PALMVEIN_STATUS_SLEEPED;
	palmveinModuleStatus.ctrlId = PALMVEIN_CTRL_MAX;
}

/**
  * @brief  掌静脉模组睡眠处理
  * @note
  */
static void Palmvein_Sleep_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;

	switch (parambuf->event)
	{
			//终止操作完成
		case PALMVEIN_EVENT_ABORT_FINISH:
			//待机状态
			PALMVEIN_TASK_LOG(" abort finish");
			self_learn_timeout = OSAL_GetTickCount();
			//TODO 调试使用
			if(palmveinModuleStatus.curMode == PALMVEIN_MODULE_ENROLL_MODE || palmveinModuleStatus.curMode == PALMVEIN_MODULE_DELETE_MODE)
			{
				Palmvein_P_Send_GetAllUserid_CMD();  //获取已注册的用户id
			}
			break;


			//获取所有注册用户
		case PALMVEIN_EVENT_GET_ALL_USERID:
			// Palmvein_PowerDown_DealFun();		//直接下电
			CtrlId_ReadRingBuff();
			break;

			//模组存在多余id，删除完成
		case PALMVEIN_EVENT_DELETE_FINISH:
			Palmvein_P_Send_GetAllUserid_CMD();
			break;

			//模组睡眠完成
		case PALMVEIN_EVENT_SLEEP_FINISH:
			Palmvein_PowerDown_DealFun();
			break;

			//超时
		default:
			Palmvein_PowerDown_DealFun();
			break;		
	}
}

/**
  * @brief  掌静脉模组设置完成处理
  * @note
  */
static void Palmvein_SettingFinish_Process(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;

	switch(parambuf->result)
	{
		case RESULT_SUCCESS_REPORT:
			
			if(palmveinModuleStatus.ctrlId == PALMVEIN_CTRL_SET_RELEASE_ENC)
			{
				//设置量产标志位
				Palmvein_SetPalmveinReleaseFlag(1);
				Palmvein_PublishMsg(PALMVEIN_ACTION_ENC_SUCCESS,INVALID_NUM);
			}

			break;

		case RESULT_ENCRYPTED:
			//设置量产标志位
			Palmvein_SetPalmveinReleaseFlag(1);
			Palmvein_PublishMsg(PALMVEIN_ACTION_ENC_SUCCESS,INVALID_NUM);
			break;

		default:
			break;

	}

	palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
	Palmvein_Event_Deal(&parambuf);
}

/**
  * @brief  掌静脉模组设置
  * @note
  */
static void Palmvein_Setting_DealFun(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;
	PalmVeinActionType_enum_t action = PALMVEIN_ACTION_MAX;


	switch (parambuf->event)
	{
			//获取版本号
		case PALMVEIN_EVENT_GET_VERSION:
			Palmvein_P_Send_Get_Version_CMD();
			break;

			//设置演示模式
		case PALMVEIN_EVENT_SET_DEMO_MODE:
			Palmvein_P_Send_SetDemoMode_CMD(0x01);
			break;

			//设置工作模式
		case PALMVEIN_EVENT_SET_WORK_MODE:
			Palmvein_P_Send_SetDemoMode_CMD(0x00);
			break;

			//设置量产秘钥
		case PALMVEIN_EVENT_SET_RELEASE_ENC_KEY:
			Palmvein_P_Send_ReleaseEncrytionKeyNum_Cmd((uint8_t *)&palmveinKeyIndex, PALMVEIN_KEY_SIZE);
			break;

			//设置完成
		case PALMVEIN_EVENT_SET_FINISH:
			Palmvein_SettingFinish_Process(param);
			break;

			//超时
		case PALMVEIN_EVENT_TIMEOUT:
			action = PALMVEIN_ACTION_TIME_OUT;
			Palmvein_PublishMsg(action,INVALID_NUM);
			Palmvein_PowerDown_DealFun();
			break;

		default:
			action = PALMVEIN_ACTION_TIME_OUT;
			Palmvein_PublishMsg(action,INVALID_NUM);
			Palmvein_PowerDown_DealFun();
			break;

	}
}



static void Palmvein_Mode_Update(PalmVein_ctrl_enum_t msgId)
{
	PalmVein_ctrl_enum_t ctrlId = msgId;
	

	switch(ctrlId)
	{
		case PALMVEIN_CTRL_ENROLL:
			palmveinModuleStatus.curMode = PALMVEIN_MODULE_ENROLL_MODE;
			break;

		case PALMVEIN_CTRL_VERIFY:
		case PALMVEIN_CTRL_VERIFY_DELETE:
			palmveinModuleStatus.curMode = PALMVEIN_MODULE_VERIFY_MODE;
			break;

		case PALMVEIN_CTRL_DELETE:
		case PALMVEIN_CTRL_FACTORY_RESET:
			palmveinModuleStatus.curMode = PALMVEIN_MODULE_DELETE_MODE;
			break;

		case PALMVEIN_CTRL_ABORT:
			palmveinModuleStatus.curMode = PALMVEIN_MODULE_IDLE_MODE;
			break;

		case PALMVEIN_CTRL_SET_DEMO_MODE:
        case PALMVEIN_CTRL_SET_WORK_MODE:
        case PALMVEIN_CTRL_SET_RELEASE_ENC:
        case PALMVEIN_CTRL_GET_VERSION:
			palmveinModuleStatus.curMode = PALMVEIN_MODULE_SET_MODE;
			break;

		case PALMVEIN_CTRL_OTA_POWER:
			palmveinModuleStatus.curMode = PALMVEIN_MODULE_OTA_MODE;
			break;

		case PALMVEIN_CTRL_START_OTA:
			palmveinModuleStatus.curMode = PALMVEIN_MODULE_OTA_MODE;
			break;


	}
	PALMVEIN_TASK_LOG("update cur mode: %d\r\n",palmveinModuleStatus.curMode);

}



/**
  * @brief  掌静脉模式选择处理
  *
  * @note
  */
static void Palmvein_Mode_SeletDeal(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;

	PALMVEIN_TASK_LOG("selet curMode :%d, event: %d, result :%d",palmveinModuleStatus.curMode,parambuf->event,parambuf->result);
	switch (palmveinModuleStatus.curMode)
	{
			//验证
		case PALMVEIN_MODULE_VERIFY_MODE:
			Palmvein_Verify_DealFun(parambuf);
			break;

			//录入
		case PALMVEIN_MODULE_ENROLL_MODE:
			Palmvein_Enroll_DealFun(parambuf);
			break;
			
			//删除
		case PALMVEIN_MODULE_DELETE_MODE:
			Palmvein_Delete_DealFun(parambuf);
			break;

			//设置模式
		case PALMVEIN_MODULE_SET_MODE:
			Palmvein_Setting_DealFun(parambuf);
			break;

			//ota
		case PALMVEIN_MODULE_OTA_MODE:
			Palmvein_Ota_DealFun(parambuf);
			break;
		
		
		default:
			break;
	}

}



/**
  * @brief  API操作队列读取
  * 
  * @note   	
  */
static ErrorStatus CtrlId_ReadRingBuff(void)
{
	Palmvein_Param_stu_t parambuf;

	if (OSAL_RingBufferRead(palmveinCtrl_rbHandle, &parambuf) == SUCCESS)
	{
		PALMVEIN_TASK_LOG("ctrl id read actionId %d",parambuf.actionId);
		palmveinModuleStatus.ctrlId = parambuf.actionId;
		palmveinMsgParam.actionId = parambuf.actionId;
		palmveinMsgParam.num = parambuf.num;
		palmveinMsgParam.type = parambuf.type;
		PALMVEIN_TASK_LOG("msg param , num:%d,type:%d",palmveinMsgParam.num,palmveinMsgParam.type);
		palmveinModuleStatus.curStatus = PALMVEIN_STATUS_EXECUTE;

		Palmvein_Mode_Update(parambuf.actionId);
		Palmvein_Event_Update();

		return SUCCESS;
	}

	return ERROR;
}


/**
  * @brief  API操作队列写入
  * @param  msgId:消息id
  * 
  * @note   	
  */
static ErrorStatus CtrlId_WriteRingBuff(PalmVein_ctrl_enum_t msgId, uint8_t param,uint8_t param2)
{
	Palmvein_Param_stu_t data;
	data.actionId = msgId;
	data.num = param;
	data.type = param2;
	PALMVEIN_TASK_LOG("write master msg to ringbuff");

	if (palmveinCtrl_rbHandle != NULL)
	{
		if (ERROR == OSAL_RingBufferWrite(palmveinCtrl_rbHandle, &data))
		{
			PALMVEIN_TASK_LOG("write master msg to palmvein ring fail");
		}
	}
}


/**
  * @brief 断电处理函数
  * @param 
  * @note  断电时要保证自学习完成
  */
static void Palmvein_Poweroff_process(void)
{
	uint32_t currentTime = OSAL_GetTickCount();
	power_off_flag = SET;

	//已完成了自学习和当前发送状态为空闲
	if((OSAL_PastTime(currentTime, self_learn_timeout) > 120) && (PalmveinCom_Get_TxStatus() == 0))
	{
		Palmvein_PowerDown_DealFun();
	}
	else
	{
		OSAL_EventSingleCreate(COMP_PALMVEIN, EVENT_PALMVEIN_POWER_OFF, 120, EVT_PRIORITY_MEDIUM);
	}
}

/**************************************API接口   START*************************************************/

/**
  * @brief  掌静脉控制流程
  * @param  msgId:消息id
  * @param  param1:参数1
  * @param  param2:参数2
  * 
  * @note   
  * 		
  */
static void Palmvein_ProcessMbox(uint8_t *msg)
{
    PALMVEIN_TASK_LOG("mbox msg:%d",msg[1]);

	if(msg[0] == PALMVEIN_MBOX_CTRL)
	{
		switch (msg[1])
		{
			case PALMVEIN_CTRL_DELETE:			//删除
				if(PALMVEIN_DELETE_ALL_NUN == msg[2]) //删除全部
				{
					Palmvein_DeleteAllNormalIndex();	//删除所有普通用户
				}
				else //删除单个
				{
					Palmvein_ReadUserId(msg[2], &id_to_delete);
					PALMVEIN_TASK_LOG("delete num:%d,userid: %0x4",msg[2],id_to_delete);
					Palmvein_DeleteIndex(msg[2]);
				}

				if(palmveinModuleStatus.curStatus == PALMVEIN_STATUS_EXECUTE)
				{
					//终止操作
					palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
					Palmvein_P_Send_Reset_CMD();
				}

				break;

			case PALMVEIN_CTRL_FACTORY_RESET:	//恢复出厂设置
				Palmvein_DeleteAllIndex();
				break;

			case PALMVEIN_CTRL_ENROLL:			//录入
				if(palmveinModuleStatus.curStatus == PALMVEIN_STATUS_EXECUTE)
				{
						//终止操作
					palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
					Palmvein_P_Send_Reset_CMD();
				}
				break;

			case PALMVEIN_CTRL_GET_VERSION:
			case PALMVEIN_CTRL_VERIFY:			//验证
			case PALMVEIN_CTRL_VERIFY_DELETE:	//验证删除
			case PALMVEIN_CTRL_SET_DEMO_MODE:	//设置演示模式		
			case PALMVEIN_CTRL_SET_WORK_MODE:	//设置工作模式
			case PALMVEIN_CTRL_SET_RELEASE_ENC:	//设置量产秘钥
				break;

			case PALMVEIN_CTRL_ABORT:           //终止
				if(palmveinModuleStatus.curStatus == PALMVEIN_STATUS_POWER_ON)
				{
					palmveinModuleStatus.timeout = FOREVER_TIME_OUT;
					Palmvein_PowerDown_DealFun();
				}
				else if(palmveinModuleStatus.curStatus == PALMVEIN_STATUS_EXECUTE)
				{
					//终止操作
					palmveinModuleStatus.curStatus = PALMVEIN_STATUS_IDLE;
					Palmvein_P_Send_Reset_CMD();
				}
				return;
				
			case PALMVEIN_CTRL_POWER_OFF:
				Palmvein_Poweroff_process();
				return;

			case PALMVEIN_CTRL_OTA_POWER:
				break;

			default :   
				return;
		}
	}
	else if(msg[0] == PALMVEIN_MBOX_OTA_START)
	{
		//ota启动发送固件信息
		PalmveinOta_Start(&msg[2]);
		return ;
	}
	else if(msg[0] == PALMVEIN_MBOX_OTA_TEST)
	{
		PalmveinOta_StartTest();
	}
	else if(msg[0] == PALMVEIN_MBOX_OTA_PACK)
	{
		uint16_t pack_len;
		memcpy(&pack_len,&msg[2],2);
		printf("pack_len :%d\r\n",pack_len);
		if(pack_len > 0)
		{
			Palmvein_Ota_SendUpgradePack(&msg[4],pack_len);
		}
		
		return ;
	}

	power_off_flag = RESET;
	CtrlId_WriteRingBuff(msg[1],msg[2],msg[3]);
	if(palmveinModuleStatus.curStatus == PALMVEIN_STATUS_POWER_DOWN)
	{   
		Palmvein_PowerOn_DealFun();
	}
	else if(palmveinModuleStatus.curStatus == PALMVEIN_STATUS_SLEEPED)
	{
		CtrlId_ReadRingBuff();
	}


}


/**
  * @brief  掌静脉恢复出厂设置	
  * @note   
  */
static ErrorStatus Palmvein_Factory(void)
{
	PALMVEIN_TASK_LOG("Palmvein factory");
	NvPalmvein_stu_t nv_palmvein;
	int len = sizeof(NvPalmvein_stu_t) - sizeof(nv_palmvein.palmveinReleaseFlag);
	memset(&nv_palmvein.palmveinSn, 0xff, len);
	OSAL_NvWrite(OSAL_OFFSET(NvPalmvein_stu_t, palmveinSn), &nv_palmvein.palmveinSn, len);
	return SUCCESS;
}


/***************************************************************************************************/
/*********************************    API接口   END     ********************************************/
/***************************************************************************************************/



/**
  * @brief  掌静脉事件处理
  * @param  param:处理参数结构体
  * 
  * @note   
  * 		
  */
void Palmvein_Event_Deal(Palmvein_DealParam_stu_t *param)
{
	Palmvein_DealParam_stu_t *parambuf = param;

	switch (palmveinModuleStatus.curStatus)
	{
			//上电，加密
		case PALMVEIN_STATUS_POWER_ON:
		case PALMVEIN_STATUS_ENCRYPTION:
			//TODO 模组加密有问题，暂时不加密
			Palmvein_Encryp_DealFun(parambuf);
			// Palmvein_Not_Encryp_DealFun(parambuf);
			break;

			//执行中
		case PALMVEIN_STATUS_EXECUTE:
			Palmvein_Mode_SeletDeal(parambuf);
			break;

			//空闲
		case PALMVEIN_STATUS_IDLE:
			Palmvein_Idle_DealFun(parambuf);
			break;

			//睡眠
		case PALMVEIN_STATUS_SLEEPED:
			if(CtrlId_ReadRingBuff() != SUCCESS)
			{
				Palmvein_Sleep_DealFun(parambuf);
			}
			break;

		default:
			break;
	}
}


/**
  * @brief 超时处理函数
  * @param 
  * @note  
  */
static void Palmvein_TimeoutDeal(void)
{
	uint32_t currentTime = OSAL_GetTickCount();
	Palmvein_DealParam_stu_t DealParam;

	if ((palmveinModuleStatus.timeout != FOREVER_TIME_OUT)											 //非永远不超时
		&& (OSAL_PastTime(currentTime, palmveinModuleStatus.start_time) > palmveinModuleStatus.timeout)) //判断是否超时
	{
		PALMVEIN_TASK_LOG("power on timeout\r\n");
		palmveinModuleStatus.timeout = FOREVER_TIME_OUT;
		palmveinModuleStatus.curStatus = PALMVEIN_STATUS_EXECUTE;
		PalmveinEncrypt_Set_EnFlag(1); //加密通信
		Palmvein_Event_Update();
		palmvein_err_process(1);
	}
}

/**
  * @brief 创建周期事件
  * @param 
  * @note  
  */
static void Palmvein_Create_Repeat_Event(void)
{
	/* 创建定时处理掌静脉协议 */
	OSAL_EventRepeatCreate(COMP_PALMVEIN, EVENT_PALMVEIN_RECV_MSG, 10, EVT_PRIORITY_MEDIUM);
	/* 创建超时检测协议 */
	OSAL_EventRepeatCreate(COMP_PALMVEIN, EVENT_PALMVEIN_TIME_OUT, 20, EVT_PRIORITY_MEDIUM);
	/*掌静脉模组环形消息处理*/
	OSAL_EventRepeatCreate(COMP_PALMVEIN, EVENT_PALMVEIN_SEND_MSG, 20, EVT_PRIORITY_MEDIUM);
}



/**
  * @brief 删除周期事件
  * @param 
  * @note  
  */
static void Palmvein_Delete_Event(void)
{
	OSAL_EventDelete(COMP_PALMVEIN, EVENT_PALMVEIN_RECV_MSG);
	OSAL_EventDelete(COMP_PALMVEIN, EVENT_PALMVEIN_TIME_OUT);
	OSAL_EventDelete(COMP_PALMVEIN, EVENT_PALMVEIN_SEND_MSG);
	OSAL_EventDelete(COMP_PALMVEIN, EVENT_PALMVEIN_POWER_OFF);

}







/**
  * @brief  掌静脉初始化
  *
  * @note
  */
static void Palmvein_Init(void)
{
	__EFRAM static uint8_t init_flag = 0;
	uint8_t palmveinVersion[PALMVEIN_VERSION_LEN+1] = {0};
	uint8_t len = 0;
	
    /*操作控制队列*/
	palmveinCtrl_rbHandle = OSAL_RingBufferCreate(PALMVEIN_TX_CMD_BUFF_NUM, sizeof(Palmvein_Param_stu_t));

    /*获取版本号*/
	ErrorStatus ret = Palmvein_Read_Version(palmveinVersion, &len);
	if (ret == ERROR || init_flag == 0)
	{
		init_flag = 1;
		PALMVEIN_TASK_LOG("get version");
        CtrlId_WriteRingBuff(PALMVEIN_CTRL_GET_VERSION,0,0); 
        Palmvein_PowerOn_DealFun();
	}
	else
	{
		PALMVEIN_TASK_LOG("palmvein version : %s", palmveinVersion);
	}
}




/**
  * @brief  Palmvein_Task任务函数
  *
  * @note   1.任务函数内不能写阻塞代码
  *         2.任务函数每次运行只处理一个事件
  *         3.任务函数必须添加到osal_config.h文件里面
  *
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t Palmvein_Task(uint32_t event)
{
	if (event & EVENT_SYS_START) //任务启动
	{
		PALMVEIN_TASK_LOG("palmvein task start\r\n");

        PalmveinCom_Init();
        Palmvein_Create_Repeat_Event();
		/* 掌静脉初始化 */
		Palmvein_Init();

		return (event ^ EVENT_SYS_START);
	}

    if (event & EVENT_SYS_MBOX)
    {
        while (OSAL_MboxAccept(mPox_buffer))
        {
            Palmvein_ProcessMbox(mPox_buffer);
        }
        return ( event ^ EVENT_SYS_MBOX );
    }

	/* 休眠处理 */
	if (event & EVENT_SYS_SLEEP)
	{
		PALMVEIN_TASK_LOG("palmvein task sleep\r\n");
        PalmveinCom_SleepProcess();
        OSAL_RingBufferReset(palmveinCtrl_rbHandle);
		Palmvein_Delete_Event();
		return (event ^ EVENT_SYS_SLEEP);
	}

	/* 发送给掌静脉数据的循环队列处理 */
	if (event & EVENT_PALMVEIN_SEND_MSG)
	{
		PalmveinCom_SendMsgProcess();
		return (event ^ EVENT_PALMVEIN_SEND_MSG);
	}

	/* 掌静脉协议处理 */
	if (event & EVENT_PALMVEIN_RECV_MSG)
	{
		PalmveinCom_RecvMsgProcess();
		return (event ^ EVENT_PALMVEIN_RECV_MSG);
	}

	/* 掌静脉任务超时事件 */
	if (event & EVENT_PALMVEIN_TIME_OUT)
	{
		Palmvein_TimeoutDeal();
		return (event ^ EVENT_PALMVEIN_TIME_OUT);
	}

	/* 掌静脉ota完成超时事件 */
	if (event & EVENT_PALMVEIN_OTA_TIMEOUT)
	{
		Palmvein_PublishMsg(PALMVEIN_ACTION_OTA_ERR,0);
		return (event ^ EVENT_PALMVEIN_OTA_TIMEOUT);
	}

	/* 掌静脉断电事件*/
	if (event & EVENT_PALMVEIN_POWER_OFF)
	{
		if(power_off_flag)
		{
			Palmvein_PowerDown_DealFun();
		}
		return (event ^ EVENT_PALMVEIN_POWER_OFF);
	}

	if (event & EVENT_PALMVEIN_GET_STATUS)
	{
		Palmvein_P_Send_GetOtaStatus_CMD();		//获取ota状态
		return (event ^ EVENT_PALMVEIN_GET_STATUS);
	}

	return 0;
}
COMPONENT_TASK_EXPORT(COMP_PALMVEIN, Palmvein_Task, PALMVEIN_NV_SIZE);